/**
 * jims
 */
package com.jims.master.modules.sync.service;

import com.jims.master.common.config.Global;
import com.jims.master.common.persistence.Page;
import com.jims.master.common.service.TreeService;
import com.jims.master.common.utils.CacheUtils;
import com.jims.master.common.utils.ChineseCharToEnUtils;
import com.jims.master.modules.sync.dao.ClinicItemDictDao;
import com.jims.master.modules.sync.dao.LabTypeDao;
import com.jims.master.modules.sync.dao.LabVsClinicDao;
import com.jims.master.modules.sync.entity.ClinicItemDict;
import com.jims.master.modules.sync.entity.LabType;
import com.jims.master.modules.sync.entity.LabVsClinic;
import com.jims.master.modules.sys.dao.DictDao;
import com.jims.master.modules.sys.dao.OrgDeptDao;
import com.jims.master.modules.sys.entity.Dict;
import com.jims.master.modules.sys.entity.OrgDept;
import com.jims.master.modules.sys.utils.DictUtils;
import org.apache.commons.io.FileUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

/**
 * 检验类别Service
 * @author 赵宁
 * @version 2017-02-24
 */
@Service
@Transactional(readOnly = true)
public class LabTypeService extends TreeService<LabTypeDao, LabType> {
    @Autowired
    private LabTypeDao labTypeDao;
    @Autowired
	private OrgDeptDao orgDeptDao;
    @Autowired
	private ClinicItemDictDao clinicItemDictDao;
    @Autowired
	private LabVsClinicDao labVsClinicDao;
    @Autowired
	private DictDao dictDao;

	public LabType get(String id) {
		return super.get(id);
	}

	public List<LabType> findList(LabType labType) {
		return super.findList(labType);
	}

	public Page<LabType> findPage(Page<LabType> page, LabType labType) {
		return super.findPage(page, labType);
	}

	/**
	 * 保存（修改）信息
	 * @param labType
	 * @return
	 * @author 赵宁
	 */
	@Transactional(readOnly = false)
	public int save(LabType labType) {
        if(labType.getParent()!=null && !"0".equals(labType.getParent().getId()) && !"".equals(labType.getParent().getId())){
			 labType.setLevel("2");
		}else{
			 labType.setLevel("1");
		}
		return super.save(labType);
	}

	@Transactional(readOnly = false)
	public int delete(LabType labType) {
		return super.delete(labType);
	}

    /**
     * 根据检验项目id查找其诊疗项目集合
     * @param id
     * @return
     * @Author 陈晓阳
     */
    public List<LabType> queryBylabTypeId(String id) {
        return labTypeDao.queryBylabTypeId(id);
    }
    /**
     * 根据检验项目id查找其诊疗项目集合（筛选出病人没有的项目）
     * @return
     * @Author 陈晓阳
     */
    public List<LabType> tjQueryBylabTypeId(String id, String patientId, String clinicId) {
        return dao.tjQueryBylabTypeId(id, patientId, clinicId);
    }

    /**
     * @Title: 导入检验类别
     * @Description:
     * @Param:
     * @Return:
     * @Author: fengyg
     * @Date: 2018-01-16 下午 03:45
     * version: V1.0
     */
	@Transactional(readOnly = false)
	public int importLabTypeExcel(MultipartFile myfiles) {
		int num = 0;
		String fileName = "";
		try {
			fileName = myfiles.getOriginalFilename();
			if (myfiles.isEmpty()) {
				//System.out.println("文件未上传");
			} else if (fileName.endsWith("xls") || fileName.endsWith("xlsx")) {
				//如果用的是Tomcat服务器，则文件会上传到   {服务发布位置}\\WEB-INF\\upload\\文件夹中
				String realPath = Global.getProjectPath() + "main/webapp/static/";
				//这里不必处理IO流关闭的问题，因为FileUtils.copyInputStreamToFile()方法内部会自动把用到的IO流关掉，我是看它的源码才知道的
				FileUtils.copyInputStreamToFile(myfiles.getInputStream(), new File(realPath, myfiles.getOriginalFilename()));
			}

			File file = new File(Global.getProjectPath() + "main/webapp/static/" + fileName);
			InputStream is = new FileInputStream(file.getAbsolutePath());
			// jxl提供的Workbook类
			Workbook wb = null;
			if (fileName.endsWith("xls")) {
				//2003
				wb = new HSSFWorkbook(is);
			} else if (fileName.endsWith("xlsx")) {
				//2007
				wb = new XSSFWorkbook(is);
			}
			// Excel的页签数量
			int sheet_size = wb.getNumberOfSheets();
			for (int index = 0; index < sheet_size; index++) {
				// 每个页签创建一个Sheet对象
				Sheet sheet = wb.getSheetAt(index);
				// sheet.getRows()返回该页的总行数
				//获得当前sheet的开始行
				int firstRowNum = sheet.getFirstRowNum();
				//获得当前sheet的结束行
				int lastRowNum = sheet.getLastRowNum();
				//循环除了第一行的所有行
				for (int rowNum = firstRowNum + 1; rowNum <= lastRowNum; rowNum++) {
					//获得当前行
					Row row = sheet.getRow(rowNum);
					if (row == null) {
						continue;
					}
					//获得当前行的开始列
					int firstCellNum = row.getFirstCellNum();
					//获得当前行的列数
					int lastCellNum = row.getPhysicalNumberOfCells();
					String[] cells = new String[row.getPhysicalNumberOfCells()];
					LabType labType = new LabType();
					labType.preInsert();
					labType.updateOrgId();
					labType.setDelFlag("0");
					//循环此行所有单元格
					String cellValue = "";
					for (int cellNum = firstCellNum; cellNum < lastCellNum; cellNum++) {
						Cell cell = row.getCell(cellNum);
						cellValue = getCellValue(cell).trim();
						switch (cellNum) {
							case 0:  //类别名称
								labType.setName(cellValue.trim());
								break;
							case 1:  //执行科室
								OrgDept dept = new OrgDept();
								dept.updateOrgId();
								dept.setDeptName(cellValue.trim());
								//OrgDept orgDept = orgDeptDao.findLastLowDept(dept);
								OrgDept orgDept = null;
								if (null != orgDept) {
									labType.setPerformedBy(orgDept.getId());
								}
								break;
							case 2:  //排序
								labType.setSort(Integer.parseInt(cellValue.trim()));
								break;
							case 3: //层级
								labType.setLevel(cellValue.trim());
								break;
							case 4:  //父级
								if (null == cellValue || cellValue.trim().equals("")) {
									LabType parent = new LabType();
									parent.setId("0");
									labType.setParent(parent);
									labType.setParentIds("0,");
								} else {
									LabType parent = new LabType();
									parent.updateOrgId();
									parent.setName(cellValue.trim());
									parent = labTypeDao.findLastLevelLabType(parent);
									if (null != parent) {
										labType.setParent(parent);
										labType.setParentIds("0," + parent.getId());
									}
								}
								break;
						}
					}
					int insert = labTypeDao.insert(labType);
					if (insert > 0) {
						num += insert;
					} else {
						return 0;
					}
				}
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		//清除字典缓存
		CacheUtils.remove(DictUtils.CACHE_DICT_MAP);
		return num;
	}

	/**
	 * @Title: 导入检验项目
	 * @Description:
	 * @Param:
	 * @Return:
	 * @Author: fengyg
	 * @Date: 2018-01-16 下午 04:12
	 * version: V1.0
	 */
	@Transactional(readOnly = false)
	public int importLabVsExcel(MultipartFile myfiles) {
		int num = 0;
		String fileName = "";
		List<ClinicItemDict> errorItemDict = new ArrayList<>();
		List<LabType> errorLabTypeList = new ArrayList<>();
		try {
			fileName = myfiles.getOriginalFilename();
			if (myfiles.isEmpty()) {
				//System.out.println("文件未上传");
			} else if (fileName.endsWith("xls") || fileName.endsWith("xlsx")) {
				//如果用的是Tomcat服务器，则文件会上传到   {服务发布位置}\\WEB-INF\\upload\\文件夹中
				String realPath = Global.getProjectPath() + "main/webapp/static/";
				//这里不必处理IO流关闭的问题，因为FileUtils.copyInputStreamToFile()方法内部会自动把用到的IO流关掉，我是看它的源码才知道的
				FileUtils.copyInputStreamToFile(myfiles.getInputStream(), new File(realPath, myfiles.getOriginalFilename()));
			}

			File file = new File(Global.getProjectPath() + "main/webapp/static/" + fileName);
			InputStream is = new FileInputStream(file.getAbsolutePath());
			// jxl提供的Workbook类
			Workbook wb = null;
			if (fileName.endsWith("xls")) {
				//2003
				wb = new HSSFWorkbook(is);
			} else if (fileName.endsWith("xlsx")) {
				//2007
				wb = new XSSFWorkbook(is);
			}
			// Excel的页签数量
			int sheet_size = wb.getNumberOfSheets();
			for (int index = 0; index < sheet_size; index++) {
				// 每个页签创建一个Sheet对象
				Sheet sheet = wb.getSheetAt(index);
				// sheet.getRows()返回该页的总行数
				//获得当前sheet的开始行
				int firstRowNum = sheet.getFirstRowNum();
				//获得当前sheet的结束行
				int lastRowNum = sheet.getLastRowNum();
				//循环除了第一行的所有行
				for (int rowNum = firstRowNum + 1; rowNum <= lastRowNum; rowNum++) {
					//获得当前行
					Row row = sheet.getRow(rowNum);
					if (row == null) {
						continue;
					}
					//获得当前行的开始列
					int firstCellNum = row.getFirstCellNum();
					//获得当前行的列数
					int lastCellNum = row.getPhysicalNumberOfCells();
					String[] cells = new String[row.getPhysicalNumberOfCells()];
					LabVsClinic labVsClinic = new LabVsClinic();
					labVsClinic.preInsert();
					labVsClinic.setDelFlag("0");
					LabType labType = new LabType();
					labType.setDelFlag("0");
					labType.updateOrgId();
					ClinicItemDict clinicItemDict = new ClinicItemDict();
					clinicItemDict.setDelFlag("0");
					clinicItemDict.updateOrgId();
					//循环此行所有单元格
					String cellValue = "";
					for (int cellNum = firstCellNum; cellNum < lastCellNum; cellNum++) {
						Cell cell = row.getCell(cellNum);
						cellValue = getCellValue(cell).trim();
						switch (cellNum) {
							case 0:  //检验类别名称
								labType.setName(cellValue.trim());
								break;
							case 1:  //检验项目编码
								clinicItemDict.setItemCode(cellValue.trim());
								break;
							case 2:  //检验项目名称
								clinicItemDict.setItemName(cellValue.trim());
								break;
							case 3:  //标本
								Dict specimenDict = new Dict();
								specimenDict.setType("SPECIMAN_DICT");
								specimenDict.setLabel(cellValue.trim());
								//String specimen = dictDao.getValue(specimenDict);
								String specimen = "";
								if (null != specimen && !specimen.trim().equals("")) {  //此标本已经存在，直接赋值
									labVsClinic.setSpecimen(specimen);
								} else {
									//String newSpecimen = DictUtils.getUnitsValue("SPECIMAN_DICT");
									Dict dict = new Dict();
									dict.preInsert();
									//dict.setValue(newSpecimen);
									dict.setLabel(cellValue.trim());
									dict.setInputCode(ChineseCharToEnUtils.getAllFirstLetter(dict.getLabel()));
									dict.setType("SPECIMAN_DICT");
									dict.setDescription("检验标本");
									dict.setDelFlag("0");
									dict.setRemarks("自动生成");
									dictDao.insert(dict);
									//labVsClinic.setSpecimen(newSpecimen);
								}
								break;
							case 4: //执行科室
								OrgDept orgDept = new OrgDept();
								orgDept.setDelFlag("0");
								orgDept.updateOrgId();
								orgDept.setDeptName(cellValue.trim());
								//orgDept = orgDeptDao.findLastLowDept(orgDept);
								labVsClinic.setPerformedBy(orgDept.getId());
								break;
							case 5:  //排序
								labVsClinic.setSort(Integer.parseInt(cellValue.trim()));
								break;
						}
					}
					ClinicItemDict oldClinicItemDict = clinicItemDictDao.findByCodeName(clinicItemDict);
					if (null != oldClinicItemDict) {
						labVsClinic.setClinicId(oldClinicItemDict.getId());
						labVsClinic.setClinicItemDict(oldClinicItemDict);
						LabType oldLabType = labTypeDao.findLastLevelLabType(labType);
						if (null != oldLabType) {
							if (!oldLabType.getLevel().equals("1")) {
								labVsClinic.setLabId(oldLabType.getId());
								labVsClinic.setLabType(oldLabType);
							} else {
								labType.setName(clinicItemDict.getItemName());
								LabType oldLabType2 = labTypeDao.findLastLevelLabType(labType);
								if (null != oldLabType2) {
									labVsClinic.setLabId(oldLabType2.getId());
									labVsClinic.setLabType(oldLabType2);
								} else {
									errorLabTypeList.add(labType);  //检验类别不存在
								}
							}
							if (labVsClinic.getLabType() != null && labVsClinic.getClinicItemDict() != null) {
								int insert = labVsClinicDao.insert(labVsClinic);
								if (insert > 0) {
									num += insert;
								} else {
									return 0;
								}
							}
						} else {
							errorLabTypeList.add(labType);   //检验类别不存在
						}
					} else {
						errorItemDict.add(clinicItemDict);  //诊疗项目不存在
					}
				}
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		if (null != errorItemDict && errorItemDict.size() > 0) {
			for (ClinicItemDict clinicItemDict : errorItemDict) {
				//System.out.println("诊疗项目不存在：" + clinicItemDict.getItemCode() + "--" + clinicItemDict.getItemName());
			}
		}
		if (null != errorLabTypeList && errorLabTypeList.size() > 0) {
			for (LabType labType : errorLabTypeList) {
				//System.out.println("检验类别不存在：" + labType.getName());
			}
		}
		//清除字典缓存
		CacheUtils.remove(DictUtils.CACHE_DICT_MAP);
		return num;
	}

	public static String getCellValue(Cell cell) {
		String cellValue = "";
		if (cell == null) {
			return cellValue;
		}
////        把数字当成String来读，避免出现1读成1.0的情况
//        if(cell.getCellType() == Cell.CELL_TYPE_NUMERIC){
//            cell.setCellType(Cell.CELL_TYPE_STRING);
//        }
		//判断数据的类型
		switch (cell.getCellType()) {
			case Cell.CELL_TYPE_NUMERIC: //数字
				DecimalFormat df = new DecimalFormat("0");
				cellValue = df.format(cell.getNumericCellValue());
				//cellValue = String.valueOf(cell.getNumericCellValue());
				break;
			case Cell.CELL_TYPE_STRING: //字符串
				cellValue = String.valueOf(cell.getStringCellValue());
				break;
			case Cell.CELL_TYPE_BOOLEAN: //Boolean
				cellValue = String.valueOf(cell.getBooleanCellValue());
				break;
			case Cell.CELL_TYPE_FORMULA: //公式
				cellValue = String.valueOf(cell.getCellFormula());
				break;
			case Cell.CELL_TYPE_BLANK: //空值
				cellValue = "";
				break;
			case Cell.CELL_TYPE_ERROR: //故障
				cellValue = "非法字符";
				break;
			default:
				cellValue = "未知类型";
				break;
		}
		return cellValue;
	}
}